#!/bin/bash

# Tax Web 项目部署脚本
# 系统要求：Ubuntu
# 依赖：Docker, Docker Compose, OpenJDK 17, Maven, Git

set -e  # 遇到错误立即退出

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 通用日志函数
log() {
    echo -e "$1"
}

# 错误退出函数
error_exit() {
    log_error "$1"
    exit 1
}

# 配置变量
PROJECT_NAME="JSH_ERP"
DOCKER_IMAGE_NAME="jsherp-boot-server"
DOCKER_TAG="latest"
BUILD_DIR=/data/source/jshERP-boot/deployment/build
WORK_DIR="$BUILD_DIR/$PROJECT_NAME"
BACKUP_DIR="$BUILD_DIR/backup"
# 获取脚本所在目录（deployment 目录）
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CURRENT_DIR="$SCRIPT_DIR"

# 从环境变量或参数读取配置
GIT_REPO_URL=https://gitee.com/xsfcjy/JSH_ERP.git
GIT_BRANCH=master
GIT_TOKEN=e962dcccdb1e3384645c7c5c4c1e47c7
# Maven 选项：增加内存
MAVEN_OPTS=${MAVEN_OPTS:-"-Xmx2048m -Xms1024m"}

# 检查必需的环境变量
check_env() {
    log_info "检查环境变量..."

    if [ -z "$GIT_REPO_URL" ]; then
        log_error "GIT_REPO_URL 环境变量未设置"
        echo "使用方法: export GIT_REPO_URL=https://gitee.com/xsfcjy/JSH_ERP.git"
        exit 1
    fi

    if [ -z "$GIT_TOKEN" ]; then
        log_error "GIT_TOKEN 环境变量未设置"
        echo "使用方法: export GIT_TOKEN=your_git_token"
        exit 1
    fi

    log_info "环境变量检查通过"
}

# 检查系统依赖
check_dependencies() {
    log_info "检查系统依赖..."
    log_info "系统依赖检查通过"
}

# 清理构建目录
cleanup_build_dir() {
    log_info "清理构建目录..."
    if [ -d "$BUILD_DIR" ]; then
        rm -rf "$BUILD_DIR"
    fi
    mkdir -p "$BUILD_DIR"
}

# 拉取最新代码
pull_latest_code() {
    log "${BLUE}📥 拉取最新代码...${NC}"

    # 创建或清理工作目录
    if [ -d "$WORK_DIR" ]; then
        log "${YELLOW}清理工作目录...${NC}"
        rm -rf "$WORK_DIR"
    fi

    mkdir -p "$WORK_DIR"
    cd "$WORK_DIR" || error_exit "无法切换到工作目录: $WORK_DIR"

    # 构造带token的Git URL
    if [[ $GIT_REPO_URL == https://gitee.com/* ]]; then
        # Gitee格式
        GIT_URL_WITH_TOKEN=$(echo $GIT_REPO_URL | sed "s|https://gitee.com/|https://oauth2:${GIT_TOKEN}@gitee.com/|")
    elif [[ $GIT_REPO_URL == https://github.com/* ]]; then
        # GitHub格式
        GIT_URL_WITH_TOKEN=$(echo $GIT_REPO_URL | sed "s|https://github.com/|https://${GIT_TOKEN}@github.com/|")
    else
        error_exit "不支持的Git仓库类型，仅支持Gitee和GitHub"
    fi

    # 克隆仓库
    log "${YELLOW}克隆仓库: $GIT_REPO_URL${NC}"
    if git clone --depth 1 --branch "$GIT_BRANCH" "$GIT_URL_WITH_TOKEN" .; then
        log "${GREEN}✅ 代码拉取成功${NC}"

        # 显示提交信息
        COMMIT_HASH=$(git rev-parse --short HEAD)
        COMMIT_MSG=$(git log -1 --pretty=format:"%s")
        log "${PURPLE}📝 最新提交: $COMMIT_HASH - $COMMIT_MSG${NC}"

        # 显示目录结构（用于调试）
        log_info "克隆后的目录结构:"
        log_info "当前目录: $(pwd)"
        log_info "目录内容:"
        ls -la | head -20
        if [ -d "jshERP-boot" ]; then
            log_info "找到 jshERP-boot 目录"
            if [ -f "jshERP-boot/pom.xml" ]; then
                log_info "找到 jshERP-boot/pom.xml"
            else
                log_warn "jshERP-boot 目录存在但未找到 pom.xml"
            fi
        else
            log_warn "未找到 jshERP-boot 目录"
        fi
    else
        error_exit "代码拉取失败"
    fi
}

# 检查代码变更
check_code_changes() {
    local force_deploy=${1:-false}

    log "${BLUE}🔍 检查代码变更...${NC}"

    if [ "$force_deploy" = true ]; then
        log "${YELLOW}⚡ 强制部署模式，跳过代码变更检查${NC}"
        return
    fi

    if [ -d "$BACKUP_DIR" ] && [ -d "$WORK_DIR" ]; then
        # 比较文件变更
        if diff -r "$BACKUP_DIR" "$WORK_DIR" > /dev/null 2>&1; then
            log "${YELLOW}⚠️  代码无变更，是否继续部署? (y/N)${NC}"
            read -r response
            if [[ ! "$response" =~ ^[Yy]$ ]]; then
                log "${YELLOW}部署已取消${NC}"
                exit 0
            fi
        else
            log "${GREEN}✅ 检测到代码变更${NC}"
        fi
    else
        log "${YELLOW}首次部署或无备份目录，跳过变更检查${NC}"
    fi
}

# 备份当前代码
backup_current_code() {
    if [ -d "$WORK_DIR" ]; then
        log "${BLUE}📦 备份当前代码...${NC}"

        # 创建备份目录
        mkdir -p "$(dirname "$BACKUP_DIR")"

        # 删除旧备份
        if [ -d "$BACKUP_DIR" ]; then
            rm -rf "$BACKUP_DIR"
        fi

        # 复制当前代码到备份目录
        cp -r "$WORK_DIR" "$BACKUP_DIR"
        log "${GREEN}✅ 代码备份完成${NC}"
    fi
}

# 下载代码（兼容旧版本）
download_code() {
    local force_deploy=${1:-false}

    log_info "使用新的代码拉取和变更检测流程..."

    # 拉取最新代码
    pull_latest_code

    # 检查代码变更
    check_code_changes "$force_deploy"

    # 备份当前代码
    backup_current_code

    # 切换到工作目录
    cd "$WORK_DIR"
}

# Maven构建
maven_build() {
    echo ""  # 空行分隔
    log_info "========== 开始 Maven 构建流程 =========="
    log_info "配置的工作目录 (WORK_DIR): $WORK_DIR"
    log_info "项目名称 (PROJECT_NAME): $PROJECT_NAME"
    log_info "构建目录 (BUILD_DIR): $BUILD_DIR"
    echo ""  # 空行分隔

    # 确保在正确的目录中执行
    if [ ! -d "$WORK_DIR" ]; then
        error_exit "工作目录不存在: $WORK_DIR"
    fi

    cd "$WORK_DIR" || error_exit "无法切换到工作目录: $WORK_DIR"
    
    log_info "========== Maven构建调试信息 =========="
    log_info "工作目录 (WORK_DIR): $WORK_DIR"
    log_info "当前工作目录 (pwd): $(pwd)"
    log_info "目录内容:"
    ls -la | head -20 || log_warn "无法列出目录内容"
    log_info "========================================"
    echo ""  # 空行分隔

    # 查找 pom.xml 文件
    local maven_project_dir=""
    
    # 检查当前目录
    if [ -f "pom.xml" ]; then
        maven_project_dir="$(pwd)"
        log_info "✅ 在根目录找到 pom.xml: $maven_project_dir/pom.xml"
    # 检查 jshERP-boot 子目录
    elif [ -f "jshERP-boot/pom.xml" ]; then
        cd "jshERP-boot" || error_exit "无法切换到 jshERP-boot 目录"
        maven_project_dir="$(pwd)"
        log_info "✅ 在 jshERP-boot 子目录找到 pom.xml: $maven_project_dir/pom.xml"
    else
        # 尝试查找所有 pom.xml 文件
        log_warn "⚠️  在当前目录未找到 pom.xml，搜索所有 pom.xml 文件..."
        local found_poms=$(find . -name "pom.xml" -type f 2>/dev/null | head -5)
        if [ -n "$found_poms" ]; then
            log_info "找到以下 pom.xml 文件:"
            echo "$found_poms"
            # 使用第一个找到的 pom.xml 的目录（转换为绝对路径）
            local first_pom=$(echo "$found_poms" | head -1)
            local pom_dir=$(dirname "$first_pom")
            # 如果是相对路径，转换为绝对路径
            if [[ "$pom_dir" != /* ]]; then
                cd "$pom_dir" || error_exit "无法切换到目录: $pom_dir"
                maven_project_dir="$(pwd)"
            else
                maven_project_dir="$pom_dir"
                cd "$maven_project_dir" || error_exit "无法切换到目录: $maven_project_dir"
            fi
            log_info "使用目录: $maven_project_dir"
        else
            log_error "❌ 找不到任何 pom.xml 文件"
            log_error "当前目录: $(pwd)"
            log_error "请检查代码是否已正确克隆"
            error_exit "找不到 pom.xml 文件"
        fi
    fi

    # 确保在正确的目录中
    if [ -n "$maven_project_dir" ] && [ "$(pwd)" != "$maven_project_dir" ]; then
        cd "$maven_project_dir" || error_exit "无法切换到 Maven 项目目录: $maven_project_dir"
        log_info "已切换到 Maven 项目目录: $(pwd)"
    fi

    # 最终验证 pom.xml 存在
    if [ ! -f "pom.xml" ]; then
        error_exit "无法访问 pom.xml 文件，当前目录: $(pwd)"
    fi

    log_info "✅ 确认 pom.xml 文件存在: $(pwd)/pom.xml"

    # 设置Maven选项
    export MAVEN_OPTS="$MAVEN_OPTS"
    
    # 设置 Java 编译器选项以解决 Lombok 与 Java 17 的兼容性问题
    # Lombok 1.18.12 需要这些参数才能在 Java 17 上正常工作
    export JAVA_TOOL_OPTIONS="--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"

    log_info "========== 开始 Maven 构建 =========="
    log_info "Maven构建目录: $(pwd)"
    log_info "POM 文件: pom.xml"
    log_info "MAVEN_OPTS: $MAVEN_OPTS"
    log_info "JAVA_TOOL_OPTIONS: $JAVA_TOOL_OPTIONS"
    log_info "======================================"

    # 再次验证当前目录和 pom.xml
    local current_pwd=$(pwd)
    log_info "执行 Maven 前的最终验证:"
    log_info "  当前目录: $current_pwd"
    log_info "  pom.xml 存在: $([ -f "pom.xml" ] && echo "是" || echo "否")"
    
    if [ ! -f "pom.xml" ]; then
        error_exit "致命错误: 在执行 Maven 前 pom.xml 不存在！当前目录: $current_pwd"
    fi

    # 清理并编译
    # 注意: set -e 会在命令失败时自动退出
    log_info "执行: mvn clean compile -DskipTests"
    log_info "工作目录: $(pwd)"
    mvn clean compile -DskipTests

    # 打包
    log_info "执行: mvn package -DskipTests"
    log_info "工作目录: $(pwd)"
    mvn package -DskipTests

    # 检查jar文件是否生成（根据 pom.xml 中的 finalName 配置为 jshERP）
    if [ ! -f "target/jshERP.jar" ]; then
        log_error "JAR文件未生成，期望路径: target/jshERP.jar"
        log_info "target 目录内容:"
        ls -la target/ 2>/dev/null || log_warn "target 目录不存在"
        exit 1
    fi

    log_info "Maven构建成功，JAR文件: target/jshERP.jar"
}

# 构建Docker镜像
build_docker_image() {
    log_info "构建Docker镜像..."

    # 查找包含 JAR 文件的目录
    local maven_dir=""
    
    # 首先检查 WORK_DIR 目录
    if [ -f "$WORK_DIR/target/jshERP.jar" ]; then
        maven_dir="$WORK_DIR"
        log_info "在 $WORK_DIR 找到 JAR 文件"
    elif [ -f "$WORK_DIR/jshERP-boot/target/jshERP.jar" ]; then
        maven_dir="$WORK_DIR/jshERP-boot"
        log_info "在 $WORK_DIR/jshERP-boot 找到 JAR 文件"
    else
        # 尝试搜索 JAR 文件
        log_warn "未在预期位置找到 JAR 文件，搜索中..."
        local jar_path=$(find "$WORK_DIR" -name "jshERP.jar" -type f 2>/dev/null | head -1)
        if [ -n "$jar_path" ]; then
            # jar_path 应该是 target/jshERP.jar，所以需要获取 target 的父目录
            maven_dir=$(dirname "$(dirname "$jar_path")")
            log_info "找到 JAR 文件: $jar_path"
            log_info "使用目录: $maven_dir"
        else
            error_exit "找不到 JAR 文件: target/jshERP.jar，请先执行 Maven 构建。搜索路径: $WORK_DIR"
        fi
    fi

    if [ -z "$maven_dir" ] || [ ! -d "$maven_dir" ]; then
        error_exit "无法确定 Maven 构建目录"
    fi

    cd "$maven_dir" || error_exit "无法切换到 Maven 构建目录: $maven_dir"

    # 验证 JAR 文件存在
    if [ ! -f "target/jshERP.jar" ]; then
        error_exit "找不到 JAR 文件: target/jshERP.jar，当前目录: $(pwd)"
    fi

    # 复制Dockerfile到构建目录
    if [ ! -f "$CURRENT_DIR/Dockerfile" ]; then
        error_exit "找不到 Dockerfile: $CURRENT_DIR/Dockerfile"
    fi
    cp "$CURRENT_DIR/Dockerfile" .

    log_info "Docker构建目录: $(pwd)"
    log_info "JAR文件位置: target/jshERP.jar"

    # 构建镜像
    # 注意: set -e 会在命令失败时自动退出
    docker build -t "$DOCKER_IMAGE_NAME:$DOCKER_TAG" .
    log_info "Docker镜像构建成功: $DOCKER_IMAGE_NAME:$DOCKER_TAG"
}

# 部署服务
deploy_service() {
    log_info "部署服务..."

    cd "$CURRENT_DIR"

    # 停止现有服务
    if docker-compose -f docker-compose.yml ps | grep -q "Up"; then
        log_info "停止现有服务..."
        docker-compose -f docker-compose.yml down
    fi

    # 启动服务
    # 注意: set -e 会在命令失败时自动退出
    docker-compose -f docker-compose.yml up -d
    log_info "服务部署成功"
}

# 健康检查
health_check() {
    log_info "执行健康检查..."

    # 等待服务启动
    sleep 30

    # 检查容器状态
    if docker-compose -f docker-compose.yml ps | grep -q "Up"; then
        log_info "服务运行正常"

        # 显示服务状态
        docker-compose -f docker-compose.yml ps
    else
        log_error "服务启动失败"
        docker-compose -f docker-compose.yml logs
        exit 1
    fi
}

# 清理临时文件
cleanup() {
    # 只在失败时清理（通过检查退出码）
    local exit_code=$?
    if [ $exit_code -ne 0 ]; then
        log_warn "检测到错误（退出码: $exit_code），清理临时文件..."
        if [ -d "$BUILD_DIR" ]; then
            # 保留备份目录，只清理工作目录
            if [ -d "$WORK_DIR" ]; then
                rm -rf "$WORK_DIR"
            fi
        fi
    else
        log_info "部署成功，保留构建文件以便后续使用"
    fi
}

# 显示帮助信息
show_help() {
    echo "Tax Web 部署脚本"
    echo ""
    echo "使用方法:"
    echo "  $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -h, --help     显示帮助信息"
    echo "  --build-only   仅构建，不部署"
    echo "  --deploy-only  仅部署，不构建"
    echo "  --force        强制部署，跳过代码变更检查"
    echo ""
    echo "环境变量:"
    echo "  GIT_REPO_URL   Git仓库地址 (必需)"
    echo "  GIT_TOKEN      Git访问令牌 (必需)"
    echo "  GIT_BRANCH     Git分支名称 (默认: main)"
    echo "  MAVEN_OPTS     Maven选项 (默认: -Xmx2048m -Xms1024m)"
    echo ""
    echo "示例:"
    echo "  export GIT_REPO_URL=https://gitee.com/your-org/jshERP-boot.git"
    echo "  export GIT_TOKEN=your_token_here"
    echo "  $0"
}

# 主函数
main() {
    local build_only=false
    local deploy_only=false
    local force_deploy=false

    # 解析命令行参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            --build-only)
                build_only=true
                shift
                ;;
            --deploy-only)
                deploy_only=true
                shift
                ;;
            --force)
                force_deploy=true
                shift
                ;;
            *)
                log_error "未知选项: $1"
                show_help
                exit 1
                ;;
        esac
    done

    log_info "开始Tax Web项目部署..."

    # 检查环境
    check_env
    check_dependencies

    if [ "$deploy_only" = false ]; then
        # 构建流程
        cleanup_build_dir
        download_code "$force_deploy"
        maven_build
        build_docker_image
        # 注意: cleanup 函数通过 trap 在退出时自动调用，不需要手动调用
    fi

    if [ "$build_only" = false ]; then
        # 部署流程
        deploy_service
        health_check
    fi

    log_info "部署完成！"
    # 正常退出，退出码为 0，cleanup 函数会检测到并保留文件
    exit 0
}

# 捕获退出信号，执行清理
trap cleanup EXIT

# 执行主函数
main "$@"
